package week07.necessary.batchinsert;

import lombok.extern.slf4j.Slf4j;
import week07.necessary.batchinsert.base.AbstractBatchInsertImpl;
import week07.necessary.batchinsert.entities.Orders;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.StringJoiner;
import java.util.concurrent.atomic.AtomicLong;

/**
 * 多值插入
 * @author yky
 * @since 2021/8/5 12:31
 */
@Slf4j
public class MultipleValuesInsert extends AbstractBatchInsertImpl {

    public MultipleValuesInsert(int total, int partition) {
        super(total, partition);
    }


    @Override
    public void test() throws SQLException {
        final AtomicLong atomicLong = new AtomicLong();
        Connection connection = getConnection();

        String prefix = "INSERT INTO week07.orders(user_id, trade_no, total_fee, trade_fee) VALUES";
        super.batchInsert(listCollection -> {
            for (List<Orders> ordersList : listCollection) {

                StringJoiner valueJoiner = new StringJoiner(",");
                List<Object> params = new LinkedList<>();
                for (Orders orders : ordersList) {
                    params.add(orders.getUserId());
                    params.add(orders.getTradeNo());
                    params.add(orders.getTotalFee());
                    params.add(orders.getTradeFee());
                    valueJoiner.add("(?,?,?,?)");
                }

                String finalSql = String.join(" ", prefix, valueJoiner.toString());
                try {
                    PreparedStatement preparedStatement = connection.prepareStatement(finalSql);
                    Iterator<Object> iterator = params.iterator();
                    int i = 1;
                    while (iterator.hasNext()) {
                        preparedStatement.setObject(i++, iterator.next());
                    }
                    long start = System.currentTimeMillis();
                    preparedStatement.executeUpdate();
                    atomicLong.addAndGet(System.currentTimeMillis() - start);
                } catch (SQLException e) {
                    throw new RuntimeException(e);
                }
            }
        });
        log.info("[批量插入]耗时{}毫秒", atomicLong.get());
    }
}
